package a0.reflection;


import java.lang.reflect.*;

/**
 * description:
 * author: xiaoxu
 * createTime: 2018-12-11 14:33
 **/
public class RefectionDemo {

    public static void main(String[] args) throws Exception{
        Dog dog = new Dog("wangwagn", "black", 4);
        //获取Class对象 字节码信息
        Class dogClass1 = dog.getClass();

        Class dogClass2 = Dog.class;

        try {
            Class dogClass3 = Class.forName("a0.reflection.Dog");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


        //instance1();
        //instance3();
        instance4();


    }

    //通过反射实例化对象
    public static void instance1() {
        Class<Dog> dogClass = Dog.class;
        try {
            //默认调用了无参的构造方法（没有无参构造方法会报错）
            Dog dog = dogClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //获取所有的构造方法
    public static void instance2() {
        Class<Dog> dogClass = Dog.class;

        Constructor[] constructors = dogClass.getConstructors();

        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName());
            System.out.println(constructor.getParameterCount());
        }

        //获取一个指定的构造方法
        try {
            Constructor constructor =
                    dogClass.getConstructor(String.class, String.class, Integer.class);
            //调用带参数的构造器实例化对象
            try {
                Dog dog = (Dog) constructor.newInstance("", "", 3);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }


    //获取所有的属性
    public static void instance3() {
        Class<Dog> dogClass = Dog.class;
        //获取非私有属性
        Field[] fields = dogClass.getFields();
        //System.out.println(fields.length);

        //获取所有属性
        Field[] declaredFields = dogClass.getDeclaredFields();
        //System.out.println(declaredFields.length);

        for (Field declaredField : declaredFields) {
            //获取访问修饰符
            int modifiers = declaredField.getModifiers();
            System.out.println(modifiers);
            System.out.println(Modifier.toString(modifiers));
            System.out.println(declaredField.getName());
            System.out.println(declaredField.getType());
        }


    }


    //获取方法信息
    public static void instance4() throws Exception {
        Class<Dog> dogClass = Dog.class;
        Dog dog = dogClass.newInstance();
        //获取包名
        Package aPackage = dogClass.getPackage();
        System.out.println(aPackage.getName());
        //获取公有方法，包括继承的公有方法
        Method[] methods = dogClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if (method.getName().equals("eat")){
                method.invoke(dog);
            }
        }
        //获取该对象所有方法(不包括父类方法)
        Method[] declaredMethods = dogClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
            if (declaredMethod.getName().equals("eat1")){
                //设置私有方法可以被访问（去除访问修饰符检查）
                //declaredMethod.setAccessible(true);
                declaredMethod.invoke(dog);
            }
        }
        //Dynamic


    }
}
